package com.thz.friend.service.exam.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.thz.common.core.constants.Constants;
import com.thz.common.core.pojo.TableDataInfo;
import com.thz.common.core.utlis.ThreadLocalUtil;
import com.thz.friend.manager.ExamCacheManager;
import com.thz.friend.manager.UserCacheManager;
import com.thz.friend.mapper.exam.ExamMapper;
import com.thz.friend.mapper.exam.ExamQuestionMapper;
import com.thz.friend.mapper.question.QuestionMapper;
import com.thz.friend.mapper.user.UserExamMapper;
import com.thz.friend.mapper.user.UserMapper;
import com.thz.friend.mapper.user.UserSubmitMapper;
import com.thz.friend.pojo.exam.Exam;
import com.thz.friend.pojo.exam.ExamQuestion;
import com.thz.friend.pojo.exam.dto.ExamQueryDTO;
import com.thz.friend.pojo.exam.dto.ExamRankDTO;
import com.thz.friend.pojo.exam.vo.ExamRankVO;
import com.thz.friend.pojo.exam.vo.ExamVO;
import com.thz.friend.pojo.question.Question;
import com.thz.friend.pojo.user.User;
import com.thz.friend.pojo.user.UserExam;
import com.thz.friend.pojo.user.UserSubmit;
import com.thz.friend.pojo.user.vo.UserVO;
import com.thz.friend.service.exam.IExamService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description
 * @Author thz
 * @Date 2025/3/27
 */
@Service
public class ExamServiceImpl implements IExamService {
    @Autowired
    private ExamMapper examMapper;

    @Autowired
    private ExamCacheManager examCacheManager;

    @Autowired
    private UserCacheManager userCacheManager;

    @Autowired
    private UserExamMapper userExamMapper;

    @Autowired
    private UserSubmitMapper userSubmitMapper;

    @Autowired
    private ExamQuestionMapper examQuestionMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<ExamVO> list(ExamQueryDTO examQueryDTO) {
        PageHelper.startPage(examQueryDTO.getPageNum(), examQueryDTO.getPageSize());
        return examMapper.selectExamList(examQueryDTO);
    }

    @Override
    public List<ExamVO> listHomework(Long courseId) {
        List<Exam> examList = examMapper.selectList(new LambdaQueryWrapper<Exam>()
                .select(Exam::getExamId, Exam::getTitle, Exam::getStartTime, Exam::getEndTime)
                .eq(Exam::getStatus , Constants.TRUE)
                .eq(Exam::getTypes,1)
                .eq(Exam::getCourseId,courseId)
                .orderByDesc(Exam::getCreateTime));
        List<ExamVO> examVOList = new ArrayList<>();
        Long userId = ThreadLocalUtil.get(Constants.USER_ID, Long.class);
        for (Exam exam : examList) {
            ExamVO examVO = new ExamVO();
            examVO.setExamId(exam.getExamId());
            examVO.setTitle(exam.getTitle());
            examVO.setStartTime(exam.getStartTime());
            examVO.setEndTime(exam.getEndTime());
            examVO.setScore(getScore(exam.getExamId(),courseId,userId));
            examVO.setTotalScore(getTotalScore(exam.getExamId()));
            UserExam userExam = userExamMapper.selectOne(new LambdaQueryWrapper<UserExam>()
                    .eq(UserExam::getExamId,exam.getExamId()).eq(UserExam::getUserId,userId));
            if (userExam != null) {
                examVO.setEnter(true);
            }
            examVOList.add(examVO);
        }
        return examVOList;
    }

    private Integer getTotalScore(Long examId){
        List<ExamQuestion> examQuestionList = examQuestionMapper.selectList(new LambdaQueryWrapper<ExamQuestion>()
                .select(ExamQuestion::getQuestionId)
                .eq(ExamQuestion::getExamId,examId));
        List<Integer> scoreList = new ArrayList<>();
        for (ExamQuestion examQuestion : examQuestionList) {
            Question question = questionMapper.selectOne(new LambdaQueryWrapper<Question>()
                    .select(Question::getDifficulty).eq(Question::getQuestionId,examQuestion.getQuestionId()));
            scoreList.add(question.getDifficulty()*100);
        }
        Integer score = 0;
        for (Integer score1 : scoreList) {
            score += score1;
        }
        return score;
    }


    private Integer getScore(Long examId,Long courseId,Long userId){
        List<UserSubmit> userSubmits = userSubmitMapper.selectList(new LambdaQueryWrapper<UserSubmit>()
                .select(UserSubmit::getScore)
                .eq(UserSubmit::getCourseId,courseId)
                .eq(UserSubmit::getCreateUser,userId)
                .eq(UserSubmit::getExamId,examId)
                .orderByDesc(UserSubmit::getCreateTime));

        Integer score = 0;

        for (UserSubmit userSubmit : userSubmits) {
            score += userSubmit.getScore();
        }
        return score;
    }

    @Override
    public TableDataInfo redisList(ExamQueryDTO examQueryDTO) {
        //从redis当中获取  竞赛列表的数据
        Long total = examCacheManager.getListSize(examQueryDTO.getType(), null);
        List<ExamVO> examVOList;
        if (total == null || total <= 0) {
            examVOList = list(examQueryDTO);
            examCacheManager.refreshCache(examQueryDTO.getType(), null);
            total = new PageInfo<>(examVOList).getTotal();
        } else {
            examVOList = examCacheManager.getExamVOList(examQueryDTO, null);
            total = examCacheManager.getListSize(examQueryDTO.getType(), null);
        }
        if (CollectionUtil.isEmpty(examVOList)) {
            return TableDataInfo.empty();
        }
        assembleExamVOList(examVOList);
        return TableDataInfo.success(examVOList, total);
    }

    @Override
    public TableDataInfo rankList(ExamRankDTO examRankDTO) {
//      Long total = examCacheManager.getRankListSize(examRankDTO.getExamId());
        long total = 0L;
          List<ExamRankVO> examRankVOList = new ArrayList<>();
//        if (total == null || total <= 0) {
        PageHelper.startPage(examRankDTO.getPageNum(), examRankDTO.getPageSize());
        examRankVOList = userExamMapper.selectExamRankList(examRankDTO.getExamId());

        for (ExamRankVO examRankVO : examRankVOList) {
            User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                    .select(User::getNickName)
                    .eq(User::getUserId,examRankVO.getUserId()));
            examRankVO.setNickName(user.getNickName());
        }


//            examCacheManager.refreshExamRankCache(examRankDTO.getExamId());
            total = new PageInfo<>(examRankVOList).getTotal();
//        } else {
//            examRankVOList = examCacheManager.getExamRankList(examRankDTO);
//        }
//        if (CollectionUtil.isEmpty(examRankVOList)) {
//            return TableDataInfo.empty();
//        }
//        assembleExamRankVOList(examRankVOList);
        return TableDataInfo.success(examRankVOList, total);
    }

    @Override
    public String getFirstQuestion(Long examId) {
        checkAndRefresh(examId);
        return examCacheManager.getFirstQuestion(examId).toString();
    }

    @Override
    public String preQuestion(Long examId, Long questionId) {
        checkAndRefresh(examId);
        return examCacheManager.preQuestion(examId, questionId).toString();
    }

    @Override
    public String nextQuestion(Long examId, Long questionId) {
        checkAndRefresh(examId);
        return examCacheManager.nextQuestion(examId, questionId).toString();
    }

    private void assembleExamVOList(List<ExamVO> examVOList) {
        Long userId = ThreadLocalUtil.get(Constants.USER_ID, Long.class);
        List<Long> userExamIdList = examCacheManager.getAllUserExamList(userId);
        if (CollectionUtil.isEmpty(userExamIdList)) {
            return;
        }
        for (ExamVO examVO : examVOList) {
            if (userExamIdList.contains(examVO.getExamId())) {
                examVO.setEnter(true);
            }
        }
    }

    private void assembleExamRankVOList(List<ExamRankVO> examRankVOList) {
        if (CollectionUtil.isEmpty(examRankVOList)) {
            return;
        }
        for (ExamRankVO examRankVO : examRankVOList) {
            Long userId = examRankVO.getUserId();
            UserVO user = userCacheManager.getUserById(userId);
            examRankVO.setNickName(user.getNickName());
        }
    }

    private void checkAndRefresh(Long examId) {
        Long listSize = examCacheManager.getExamQuestionListSize(examId);
        if (listSize == null || listSize <= 0) {
            examCacheManager.refreshExamQuestionCache(examId);
        }
    }

}
